#include "usart_device.h"
#include "user_global.h"
#include "crc.h"
#include "config.h"
#include "string.h"
#include "modbus.h"
#include "global.h"
#include "user_device.h"
#include "global.h"
#include "stdio.h"

/*****************************/
uchar REN0 = 1;                                  //允许接收
uchar  uart0_dr;                                 // uart0要发送长度
uchar  uart0_len = 0;                            // 已接收/或要发送长度
uchar  uart0_buf[UART0_BUF_SIZE];                // uart0发送/接收缓冲区
ushort uart0_timestamp;                          // 最后接收时间
uchar *uart0_tx_ptr;                             // 发送指针
bit uart0_rx_pending = 0;                        // uart0正在接收标志
bit uart0_tx_pending = 0;                        // uart0正在发送标志
bit uart0_delay_process = 0;            // uart0指令延时处理

uchar uart2_tx_left = 0;                // uart1发送剩余长度
uchar uart2_tx_len = 0;                 // uart1要发送长度
uchar uart2_rx_len = 0;                 // uart1已接收长度
uchar uart2_tx_buf[UART2_BUF_SIZE];     // uart1发送缓冲区
uchar uart2_rx_buf[UART2_BUF_SIZE];     // uart1接收缓冲区
ushort uart2_timestamp;                 // 最后接收时间
uchar * uart2_tx_ptr;                   // 发送指针
uchar uart2_retry_times = 0;            // uart1重试次数
uchar uart2_result = UART2_RESULT_OK;   // uart1通讯结果, 见UART1_RESULT_xxx
bit uart2_rx_pending = 0;               // uart1正在接收标志
bit uart2_tx_pending = 0;               // uart1正在发送标志
bit uart2_locked = 0;                   // uart1访问锁定

// 数据备份
uchar uart2_tx_len_bak;                 // uart1发送长度备份
uchar uart2_rx_len_bak;                 // uart1接收长度备份
uchar uart2_tx_buf_bak[UART2_BUF_SIZE]; // uart1发送缓冲区备份
uchar uart2_rx_buf_bak[UART2_BUF_SIZE]; // uart1接收缓冲区备份
uchar uart2_result_bak;                 // uart1通讯结果备份

/*****************************/
//将多字节数转换为小端模式
ushort from_little_endian_16(ushort n)
{
    return (n << 8) | (n >> 8);
}

//将多字节数转换为小端模式
ulong from_16_little_endian_32(ulong n)
{
    return  ((n << 16) & 0xFFFF0000) |
                    ((n >> 16) & 0x0000FFFF);
}
//将多字节数转换为小端模式
ulong from_little_endian_32(ulong n)
{
    return  ((n << 24) & 0xFF000000) |
            ((n << 8 ) & 0x00FF0000) |
            ((n >> 8 ) & 0x0000FF00) |
            ((n >> 24) & 0x000000FF);
}

//中段服务函数进入
void HAL_UART_RxCpltCallback(UART_HandleTypeDef huart)
{
    if(huart == USART0)
    {
        if(!REN0)
        {
            usart_data_receive(USART0);
            return;
        }
        uart0_rx_pending = 1;
        if (timer_flag_get(TIMER5, TIMER_FLAG_UP))
        {
            uart0_len = 0;
        }
        timer_counter_value_config(TIMER5, 65536-10000);
        timer_flag_clear(TIMER5, TIMER_FLAG_UP);
        uart0_buf[UART0_BUF_MASK & uart0_len++] = (uchar)usart_data_receive(USART0);
    
        uart0_timestamp = timer_counter_read(TIMER5);
    }else
    {
        //if(!REN0)
        //	return;
        uart2_rx_pending = 1;
        if (timer_flag_get(TIMER5, TIMER_FLAG_UP))
        {
            uart2_rx_len = 0;
        }
        timer_counter_value_config(TIMER5, 65536-10000);
        timer_flag_clear(TIMER5, TIMER_FLAG_UP);
        uart2_rx_buf[UART2_BUF_MASK & uart2_rx_len++] = (uchar)usart_data_receive(USART2);
        uart2_timestamp = timer_counter_read(TIMER5);
    }
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef huart)
{
    if(huart == USART0)
    {
        uart0_tx_pending = 1;
        if(uart0_len)
        {
            usart_data_transmit(USART0, *uart0_tx_ptr++);
            --uart0_len;
        }
        else{
            uart0_tx_pending = 0;
            usart_interrupt_disable(USART0, USART_INT_TBE);
        }
    }else if(huart == USART2)
    {
        uart2_tx_pending = 1;
        if(uart2_tx_left)
        {
            usart_data_transmit(USART2, *uart2_tx_ptr++);
            --uart2_tx_left;
        }
        else
            {
            uart2_tx_pending = 0;
            usart_interrupt_disable(USART2, USART_INT_TBE);
            }
    }
}


//使能发送空中断
HAL_StatusTypeDef USART0_Send_Date(uchar *data,uchar number)
{
    /* enable USART TBE interrupt */
    usart_interrupt_enable(USART0, USART_INT_TBE);
    return HAL_OK;
}

// uart0接收到了帧结束
bit Uart0_FrameEnded(void)
{
    return timer_flag_get(TIMER5, TIMER_FLAG_UP);
}

bit Uart0_Send_Message(void)
{
    HAL_StatusTypeDef hal_state;
    ushort interval;
    *(ushort*)&uart0_buf[uart0_len] = from_little_endian_16(calc_crc(uart0_buf, uart0_len));
    uart0_len += 2;
    // 距接收经过的时间
    interval = timer_counter_read(TIMER6) - uart0_timestamp;
    
    // 如果发送距接收时间不足2ms, 等待
    if (interval < 2000)
            Delay_Tick(2000 - interval);

//将uart0_buf（usart0发送缓冲区）转给uart0_tx_ptr（发送指针）
#ifndef USE_BY_ISP
    uart0_tx_ptr = uart0_buf;
    hal_state = USART0_Send_Date(uart0_buf,uart0_len);//参数没用
#else
    uart0_tx_ptr = uart0_buf;
    sbuf0 = *uart0_tx_ptr++;
    USART_SendData(USART0, sbuf0);
    USART_ITConfig(USART0, USART_IT_TXE, ENABLE);//因为是 发送寄存器空 的中断，所以发完字符串后必须关掉，否则只
    --uart0_len;
#endif

    if(hal_state != HAL_OK)
            return 0;
    return 1;
}



#ifdef _USES_UART2
////////////////////////////////////////////////////////////////////////////////
// UART1

//#define NO_GATE_WAY
#define NO_READ_RWBIT
#define NO_READ_RWWORD
//#define NO_WRITE_BIT
#define NO_READ_FILE

void UART2_START()
{
    uart2_tx_ptr = uart2_tx_buf;
    uart2_tx_len = 0;
}

void UART2_APPEND2(uint8_t type,uint32_t val)
{
    if(type == 1)
    {
        *(uchar*)&(uart2_tx_buf)[uart2_tx_len] = (uchar)val;
        uart2_tx_len += 1;
    }else if(type == 2)
    {
        val = from_little_endian_16((uint16_t)val);
        *(ushort*)&(uart2_tx_buf[uart2_tx_len]) = (ushort)val;
        uart2_tx_len += 2;
    }else if(type == 3)
    {
        val = from_little_endian_16((uint16_t)val);
        *(short*)&(uart2_tx_buf[uart2_tx_len]) = (short)val;
        uart2_tx_len += 2;
    }else if(type == 4)
    {
        val = from_little_endian_32((uint32_t)val);
        *(long*)&(uart2_tx_buf[uart2_tx_len]) = (long)val;
        uart2_tx_len += 4;
    }
}

void UART2_END()
{
    uart2_tx_left = uart2_tx_len;
}

// uart0接收到了帧结束
bit Uart2_FrameEnded(void)
{
    return timer_flag_get(TIMER5, TIMER_FLAG_UP);
}

bit USART2_Send_Date(uchar *data,uchar number)
{
    /* enable USART TBE interrupt */
    usart_interrupt_enable(USART2, USART_INT_TBE);
    return UART2_RESULT_OK;
}

// uart1发送
void Uart2_Send()
{
    uart2_rx_pending = 0;
    uart2_tx_pending = 1;
    uart2_rx_len = 0;
    uart2_tx_ptr = uart2_tx_buf;
    uart2_tx_left = uart2_tx_len;
    // 根据协议, 发送前等待4字节时间@115200
//    Delay_us(400);

    // 开始发送
    uart2_result = USART2_Send_Date(uart2_tx_buf,uart2_tx_len);
}

// uart1接收
void Uart2_Read()
{
    // 未完成接收
    if (!Uart2_FrameEnded())
        return;
    // 10ms超时
    if (uart2_rx_len == 0)
        {
            uart2_result = UART2_RESULT_TIMEOUT;
        }

    else
    {
        // 接收完成, 检查CRC
        if (uart2_rx_len < 4 || uart2_rx_len > UART2_BUF_SIZE ||
                uart2_rx_buf[0] != uart2_tx_buf[0] ||
                (uart2_rx_buf[1] & 0x7F) != uart2_tx_buf[1] ||
                !check_message_crc(uart2_rx_buf, uart2_rx_len))
        {
            uart2_result = UART2_RESULT_CRC;
        }
        else
        {
            if (uart2_rx_buf[1] & 0x80)
                uart2_result = UART2_RESULT_EXCEPTION;
            else
                uart2_result = UART2_RESULT_OK;
        }
    }

    uart2_rx_pending = 0;
}

// 通过uart1发送指令, 并等待回复
// 通讯正确返回1, uart1_result设置为UART1_RESULT_OK;
// 通讯失败返回0, uart1_result设置为错误代码
bit Uart2_Exchange_Message()
{
    // 计算CRC
    *(ushort*)&uart2_tx_buf[uart2_tx_len] = from_little_endian_16(calc_crc(uart2_tx_buf, uart2_tx_len));
    uart2_tx_len += 2;
    uart2_retry_times = UART2_MAX_RETRY_TIMES;
        
    do
    {
        uart2_locked = 1;
                Uart2_Send();
        // 等待发送完成
        while(uart2_tx_pending)
                    Main_Loop();
        // 等待接收完成
        uart2_rx_pending = 1;
        while(uart2_rx_pending)
                {
                    Main_Loop();
                    Uart2_Read();
                }
        uart2_locked = 0;
        // 从主循环恢复, 接收完成
        if (uart2_result == UART2_RESULT_OK)
            return 1;
    }
    while(--uart2_retry_times);

    return 0;
}

#ifndef NO_READ_RWBIT
bit Uart1_Read_RwBit(uchar addr, ushort index, ushort count)
{
    UART1_START();
    UART1_APPEND(uchar,  addr);
    UART1_APPEND(uchar,  0x01);
    UART1_APPEND(ushort, index);
    UART1_APPEND(ushort, count);
    UART1_END();

    return Uart1_Exchange_Message();
}
#endif

bit Uart2_Read_RoBit(uchar addr, ushort index, ushort count)
{
    UART2_START();
    UART2_APPEND2(1,  addr);
    UART2_APPEND2(1,  0x02);
    UART2_APPEND2(2, index);
    UART2_APPEND2(2, count);
    UART2_END();

    return Uart2_Exchange_Message();
}
#ifndef NO_READ_RWWORD
bit Uart1_Read_RwWord(uchar addr, ushort index, ushort count)
{
    UART1_START();
    UART1_APPEND(uchar,  addr);
    UART1_APPEND(uchar,  0x03);
    UART1_APPEND(ushort, index);
    UART1_APPEND(ushort, count);
    UART1_END();

    return Uart1_Exchange_Message();
}
#endif

bit Uart2_Read_RoWord(uchar addr, ushort index, ushort count)
{
    UART2_START();
    UART2_APPEND2(1,  addr);
    UART2_APPEND2(1,  0x04);
    UART2_APPEND2(2, index);
    UART2_APPEND2(2, count);
    UART2_END();

    return Uart2_Exchange_Message();
}

// 读取事件计数
bit Uart2_Read_Event_Count(uchar addr)
{
    UART2_START();
    UART2_APPEND2(1,  addr);
    UART2_APPEND2(1,  0x0B);
    UART2_END();

    return Uart2_Exchange_Message();
}

#ifndef NO_WRITE_BIT
void Uart2_Begin_Write_Bit(uchar addr, ushort index,ushort count)
{
    UART2_START();
    UART2_APPEND2(1,  addr);
    UART2_APPEND2(1,  0x0F);
    UART2_APPEND2(1, index);
    UART2_APPEND2(2, count);
    UART2_APPEND2(1,  ((uchar)count + 7) >> 3);
}
#endif

//拼接usart2发送内容
void Uart2_Begin_Write_Word(uchar addr, ushort index, ushort count)
{
    UART2_START();
    UART2_APPEND2(1,  addr);
    UART2_APPEND2(1,  0x10);
    UART2_APPEND2(2, index);
    UART2_APPEND2(2, count);
    UART2_APPEND2(1,  (uchar)count << 1);
}

#ifndef NO_READ_FILE
bit Uart1_Read_File(uchar addr, ushort file, ushort index, ushort count)
{
    UART1_START();
    UART1_APPEND(uchar, addr);
    UART1_APPEND(uchar, 0x14);  // 指令
    UART1_APPEND(uchar, 7);     // 字节长度
    UART1_APPEND(uchar, 6);     // 引用类型
    UART1_APPEND(ushort, file);
    UART1_APPEND(ushort, index);
    UART1_APPEND(ushort, count);
    UART1_END();

    return Uart1_Exchange_Message();
}
#endif

// 备份接收数据
void Uart2_Backup()
{
    if (uart2_locked)
    {
        // 有可能正在发送, 等待发送完成
        while(uart2_tx_pending)
                    Main_Loop();
        // 等待接收完成
        uart2_rx_pending = 1;
        while(uart2_rx_pending)
                {
                    Uart2_Read();
                }
        // 发送数据
        uart2_tx_len_bak = uart2_tx_len;
        if (uart2_tx_len)
            memcpy(uart2_tx_buf_bak, uart2_tx_buf, uart2_tx_len);

        // 接收数据
        uart2_rx_len_bak = uart2_rx_len;
        if (uart2_rx_len)
            memcpy(uart2_rx_buf_bak, uart2_rx_buf, uart2_rx_len);

        // 通讯结果
        uart2_result_bak = uart2_result;
    }
}

// 恢复备份的数据
void Uart2_Restore()
{
    if (uart2_locked)
    {
        // 发送数据
        uart2_tx_len = uart2_tx_len_bak;
        if (uart2_tx_len)
            memcpy(uart2_tx_buf, uart2_tx_buf_bak, uart2_tx_len);

        // 接收数据
        uart2_rx_len = uart2_rx_len_bak;
        if (uart2_rx_len)
            memcpy(uart2_rx_buf, uart2_rx_buf_bak, uart2_rx_len);

        // 通讯结果
        uart2_result = uart2_result_bak;

        uart2_retry_times = UART2_MAX_RETRY_TIMES;
    }
}


void Modbus_Gateway()
{
    Uart2_Backup();
    uart2_tx_len = uart0_len - 5;
    // SKIP addr + cmd + 0x0C
    memcpy(uart2_tx_buf, uart0_buf + 3, uart2_tx_len);
    // 计算CRC
    *(ushort*)&uart2_tx_buf[uart2_tx_len] = from_little_endian_16(calc_crc(uart2_tx_buf, uart2_tx_len));;
    uart2_tx_len += 2;
    Uart2_Send();

    // 等待发送完成
    while(uart2_tx_pending)
            Main_Loop();

    // 等待接收完成
    uart2_rx_pending = 1;
    while(uart2_rx_pending)
        {
            Uart2_Read();
        }
    if (uart2_rx_len > UART0_BUF_SIZE - 3) // 返回长度超过最大帧长度
        Exception_Response(ILLEGAL_DATA_VALUE);
    else if (uart2_result == UART2_RESULT_OK || uart2_result == UART2_RESULT_EXCEPTION)
    {
        // skip ADDR + 0x2B + 0x0C
        memcpy(uart0_buf + 3, uart2_rx_buf, uart2_rx_len - 2);
        // 返回的长度 - CRC长度 + (ADDR + 0x2B + 0x0C)
        uart0_len = uart2_rx_len + (3 - 2);
        Response();
    }
    else
    {
        Exception_Response(GATEWAY_TARGET_NO_RESPONSE);
    }
    Uart2_Restore();
}
 
void Modbus_Transparent()
{
    Uart2_Backup();

    uart2_tx_len = uart0_len - 5;

    // SKIP addr + cmd + 0x0C
    memcpy(uart2_tx_buf, uart0_buf + 3, uart2_tx_len);

    Uart2_Send();

    // 等待发送完成
    while(uart2_tx_pending);

    // 等待接收完成
    while(uart2_rx_pending);
    Uart2_Read();

    if (uart2_rx_len == 0)
        Exception_Response(GATEWAY_TARGET_NO_RESPONSE);
    else if (uart2_rx_len > UART0_BUF_SIZE - 5) // 超过最大长度
        Exception_Response(ILLEGAL_DATA_VALUE);
    else
    {
        memcpy(uart0_buf + 3, uart2_rx_buf, uart2_rx_len);
        uart0_len = uart2_rx_len + 3;
        Response();
    }
    Uart2_Restore();
}
#endif
